"""
Author: Broin
Date: 2023-06-18 16:27:41
LastEditTime: 2023-06-30 19:08:58
LastEditors: your name
Description: 封装后端接口
FilePath: /zhoujin/audioStreamCrypto/streamDeal.py
MADE BY BROIN
"""


from flask import Flask, request, jsonify
import ctypes
import base64
import binascii

app = Flask(__name__)


def encryptStream(data):
    lib = ctypes.CDLL("./audioDealer.so")

    encrypt_stream = lib.streamEncrypt
    encrypt_stream.argtypes = [ctypes.POINTER(ctypes.c_ubyte), ctypes.c_int]
    encrypt_stream.restype = ctypes.POINTER(ctypes.c_ubyte)

    # Get encrypted data pointer and data length
    encrypted_data_ptr = encrypt_stream(
        ctypes.cast(data, ctypes.POINTER(ctypes.c_ubyte)), len(data)
    )
    encrypted_data_len = len(data)

    # Convert pointer to bytes and print length
    encrypted_data = bytes(encrypted_data_ptr[:encrypted_data_len])
    # print(len(encrypted_data))
    return encrypted_data


def decryptStream(stream):
    lib = ctypes.CDLL("./audioDealer.so")

    size = len(stream)

    decrypt_stream = lib.streamDecrypt
    decrypt_stream.argtypes = [ctypes.POINTER(ctypes.c_ubyte), ctypes.c_int]
    decrypt_stream.restype = ctypes.POINTER(ctypes.c_ubyte)
    # Convert cipher stream to LP_c_ubyte pointer type
    ct_stream = (ctypes.c_ubyte * size).from_buffer_copy(stream)

    decrypted_data_ptr = decrypt_stream(
        ctypes.cast(ct_stream, ctypes.POINTER(ctypes.c_ubyte)), size
    )
    decrypted_data = bytes(decrypted_data_ptr[:size])
    return decrypted_data


"""
description: 判断data是否为base64编码
param {*} data
return {*}
"""


def is_base64_encoded(data):
    try:
        decoded_data = base64.b64decode(data)
        return True
    except binascii.Error:
        return False


# route
@app.route("/encrypt", methods=["POST"])
def encrypt():
    print("in encrypt")
    try:
        data = bytes(request.data)
        encrypted_data = encryptStream(data)
        base_data = base64.b64encode(encrypted_data)
        base_str = str(base_data, "utf-8")
        return jsonify({"encrypted_data": base_str})
    except Exception as e:
        # 处理异常，返回错误信息和适当的状态码
        return jsonify({"error": str(e)}), 500


@app.route("/decrypt", methods=["POST"])
def decrypt():
    try:
        res = request.data
        # 若传入数据是base64编码，先进行解码
        if is_base64_encoded(res):
            stream = base64.b64decode(res)
        else:
            stream = res
        decrypted_data = decryptStream(stream)
        # 发送时，需要知道对方需要什么类型数据，现行做法是将其重新编码为base64，封装进json:{"decrypted_data": decrypted_data_base64_str}
        base_data = base64.b64encode(decrypted_data)
        base_str = str(base_data, "utf-8")
        return jsonify({"decrypted_data": base_str})
    except Exception as e:
        # 处理异常，返回错误信息和适当的状态码
        return jsonify({"error": str(e)}), 500


if __name__ == "__main__":
    print("PORT:5000, two interfaces:")
    print('/encrypt  - encrypt stream into json:{"encrypted_data": encrypted_data}')
    print(
        '/decrypt  - decrypt encrypted stream into json:{"decrypted_data":decrypted_data}'
    )
    app.run()
